import java.net.*;
import java.util.*;
import java.io.*;

public class WaitResponseThread extends Thread {
	
	private DatagramSocket requestSocket;
	private Map<Byte, RequestThread> rtl;
	protected static Map<String, IResponse> rrtl = new HashMap<String, IResponse>();
		
	public WaitResponseThread(DatagramSocket requestSocket, Map<Byte, RequestThread> rtl) {
		super();
		this.requestSocket = requestSocket;
		this.rtl = rtl;
	}
	
	@Override
	public void run() {
		while(true) {
			try{
				byte[] buffer = new byte[MainClass.BUF_SIZE];
				DatagramPacket responsePacket = new DatagramPacket(buffer, buffer.length);			
				requestSocket.receive(responsePacket);
				
				byte respSeqNo = Util.readSeqNumber(responsePacket.getData());
				if (rtl == null) {
					throw new IllegalStateException("[ERROR]Internal state error: rtl is null.");
				}
				boolean timeout = false;
				ICommand command = null;
				synchronized (rtl) {
					timeout = !rtl.containsKey(respSeqNo);
					if (!timeout) {
						command = rtl.get(respSeqNo).getCommand();
						
						// notify the corresponding RequestThread to die
						rtl.get(respSeqNo).close();
						rtl.remove(respSeqNo);
					}
				}				
				if (timeout) {
					System.out.println("[ERROR]Received unexpected response sequence number.");
					continue;
				}
				
				IResponse resp = IResponse.createInstance(responsePacket.getData(), command);
				
				// process the response
				resp.start();
				
			} catch (SocketException e) {
				if (requestSocket.isClosed()) {
					break;
				}
				e.printStackTrace();
			} catch (IOException e) {		
				e.printStackTrace();
			}			
		}
	}

}
